/*
 * Copyright (C) 2015 Karumi.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.dome.popup.myapplication.animation;

import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.TimeInterpolator;
import android.content.res.Resources;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.View;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import android.widget.FrameLayout;

import java.util.ArrayList;
import java.util.List;

public class ExpandableSelectorAnimator {

    private static final String X_ANIMATION = "translationX";
    private static final float CONTAINER_ANIMATION_OFFSET = 1.16f;
    public static final int ANIM_TYPE_LEFT = 0;
    public static final int ANIM_TYPE_RIGHT = 1;

    private final View container;
    private final int animationDuration;
    private final int expandInterpolatorId;
    private final int containerInterpolatorId;

    private List<View> buttons;
    private int animType;

    public ExpandableSelectorAnimator(View container, int animationDuration, int expandInterpolatorId, int containerInterpolatorId) {
        this.container = container;
        this.animationDuration = animationDuration;
        this.expandInterpolatorId = expandInterpolatorId;
        this.containerInterpolatorId = containerInterpolatorId;
    }

    public void setButtons(List<View> buttons) {
        this.buttons = buttons;
    }


    public void expand(int animType) {
        this.animType = animType;
        changeButtonsVisibility(View.VISIBLE);
        expandContainer();
        expandButtons();
    }


    public void initializeButton(View button) {
        changeGravityToBottomCenterHorizontal(button);
    }

    public void reset() {
        this.buttons = new ArrayList<View>();
    }

    private void expandButtons() {
        int numberOfButtons = buttons.size();
        Animator[] animations = new Animator[numberOfButtons];
        for (int i = 0; i < numberOfButtons; i++) {
            float toX;
            View button = null;
            button = buttons.get(i);
            toX = calculateExpandedXPosition(i);
//            if(animType == ExpandableSelectorAnimator.ANIM_TYPE_LEFT){
//            }else{
//                button = buttons.get(numberOfButtons - 1 -  i);
//                toX = calculateExpandedXPosition(numberOfButtons - 1 -  i);
//            }
            TimeInterpolator interpolator = getExpandAnimatorInterpolation();

            animations[i] = createAnimatorForButton(interpolator, button, toX);
        }
        playAnimatorsTogether(animations);
    }


    private void expandContainer() {
//        float toHeight = container.getHeight();
        float toHeight = buttons.get(0).getHeight();
        Resources resources = container.getContext().getResources();
        DisplayMetrics dm = resources.getDisplayMetrics();
        int width = dm.widthPixels;
        float toWidth = width;
        Interpolator interpolator = getContainerAnimationInterpolator();
        ResizeAnimation resizeAnimation =
                createResizeAnimation(toWidth, interpolator, toHeight);
        container.startAnimation(resizeAnimation);

    }



    private ObjectAnimator createAnimatorForButton(TimeInterpolator interpolator, View button,
                                                   float toX) {
        ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(button, X_ANIMATION, toX);
        objectAnimator.setInterpolator(interpolator);
        objectAnimator.setDuration(animationDuration);
        return objectAnimator;
    }

    private ResizeAnimation createResizeAnimation(float toWidth, Interpolator interpolator,
                                                  float toHeight) {
        ResizeAnimation resizeAnimation = new ResizeAnimation(container, toWidth, toHeight);
        resizeAnimation.setInterpolator(interpolator);
        resizeAnimation.setDuration((long) (animationDuration * CONTAINER_ANIMATION_OFFSET));
        return resizeAnimation;
    }

    private void playAnimatorsTogether(Animator[] animations) {
        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.playTogether(animations);
        animatorSet.start();
    }

    private float calculateExpandedXPosition(int buttonPosition) {
        int numberOfButtons = buttons.size();
        float x = 0;
        for (int i = numberOfButtons - 1; i > buttonPosition; i--) {
            View button = buttons.get(i);
            x = x + button.getWidth() + getMarginRight(button) + getMarginLeft(button);
        }
        float returnX = animType == ANIM_TYPE_LEFT ? x : -x;
        return x;
    }

    private void changeButtonsVisibility(int visibility) {
        int lastItem = buttons.size();
        for (int i = 0; i < lastItem; i++) {
            View button = buttons.get(i);
            button.setVisibility(visibility);
        }
    }

    private TimeInterpolator getExpandAnimatorInterpolation() {
        return AnimationUtils.loadInterpolator(container.getContext(), expandInterpolatorId);
    }


    private Interpolator getContainerAnimationInterpolator() {
        return AnimationUtils.loadInterpolator(container.getContext(), containerInterpolatorId);
    }

    private int getSumWidth() {
        int sumWidth = 0;
        for (View button : buttons) {
            sumWidth += button.getWidth() + getMarginRight(button) + getMarginLeft(button);
        }
        return sumWidth;
    }

    private int getMarginRight(View view) {
        FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) view.getLayoutParams();
        return layoutParams.rightMargin;
    }

    private int getMarginLeft(View view) {
        FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) view.getLayoutParams();
        return layoutParams.leftMargin;
    }


    private void changeGravityToBottomCenterHorizontal(View view) {
        ((FrameLayout.LayoutParams) view.getLayoutParams()).gravity =
                Gravity.CENTER_VERTICAL;
    }
}
